#ifndef COMMON_MATHS_VECTOR2_H
#define COMMON_MATHS_VECTOR2_H


#include <math.h>


class Vector2;
typedef const Vector2& Vector2Arg;


class Vector2
{
public:
    enum ZeroTag { kZero };

    float       x;
    float       y;
    
                Vector2();
                Vector2(const ZeroTag&);
                Vector2(float x, float y);
    
    Vector2     operator+(Vector2Arg v) const;
    Vector2     operator-(Vector2Arg v) const;
    Vector2     operator*(Vector2Arg v) const;
    Vector2     operator/(Vector2Arg v) const;
    Vector2     operator*(float f) const;
    Vector2     operator/(float f) const;

    Vector2&    operator+=(Vector2Arg v);
    Vector2&    operator-=(Vector2Arg v);
    Vector2&    operator*=(Vector2Arg v);
    Vector2&    operator*=(float f);
    Vector2&    operator/=(float f);
    
    Vector2     operator-() const;
};


inline Vector2::Vector2()
{
}

inline Vector2::Vector2(const ZeroTag&)
    : x(0.0f), y(0.0f) { }

inline Vector2::Vector2(float x, float y)
    : x(x) , y(y) { }

inline Vector2 Vector2::operator+(Vector2Arg v) const
{
    return Vector2(x+v.x, y+v.y);
}

inline Vector2 Vector2::operator-(Vector2Arg v) const
{
    return Vector2(x-v.x, y-v.y);
}

inline Vector2 Vector2::operator*(Vector2Arg v) const
{
    return Vector2(x*v.x, y*v.y);
}

inline Vector2 Vector2::operator/(Vector2Arg v) const
{
    return Vector2(x/v.x, y/v.y);
}

inline Vector2 Vector2::operator*(float f) const
{
    return Vector2(f*x, f*y);
}

inline Vector2 Vector2::operator/(float f) const
{
    const float r = 1.0f / f;
    return Vector2(r*x, r*y);
}

inline Vector2& Vector2::operator+=(Vector2Arg v)
{
    x += v.x;
    y += v.y;
    return *this;
}

inline Vector2& Vector2::operator-=(Vector2Arg v)
{
    x -= v.x;
    y -= v.y;
    return *this;
}

inline Vector2& Vector2::operator*=(Vector2Arg v)
{
    x *= v.x;
    y *= v.y;
    return *this;
}

inline Vector2& Vector2::operator*=(float f)
{
    x *= f;
    y *= f;
    return *this;
}

inline Vector2& Vector2::operator/=(float f)
{
    const float r = 1.0f / f;
    x *= r;
    y *= r;
    return *this;
}

inline Vector2 Vector2::operator-() const
{
    return Vector2(-x, -y);
}

inline Vector2 operator*(float f, Vector2Arg v)
{
    return Vector2(f*v.x, f*v.y);
}

inline Vector2 operator/(float f, Vector2Arg v)
{
    return Vector2(f/v.x, f/v.y);
}


#endif
